﻿Imports WiremetModel.Entities.OEM
Imports WiremetModel.Specification.GeneralSpecifications
Imports WiremetModel.Entities.Interfaces
Imports WiremetModel.Entities.Tracking

Public Class AnalizaView

    Private _unitOfWork As UnitOfWork
    Private _dictDrutPracownikow As IDictionary(Of Pracownik, IList(Of Drut))

    Public Sub New()
        InitializeComponent()
        _unitOfWork = New UnitOfWork()
        dtp_DateRangeUpper.MaxDate = Now
        dtp_DateRangeLower.Value = Now.AddDays(-30)
        dtp_DateRangeUpper.Value = Now
    End Sub

    Private Sub AnalizaView_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        _unitOfWork.Dispose()
    End Sub


    Private Sub dtp_DateRangeLower_ValueChanged(sender As System.Object, e As System.EventArgs) Handles dtp_DateRangeLower.ValueChanged
        dtp_DateRangeUpper.MinDate = dtp_DateRangeLower.Value
    End Sub

    Private Sub dtp_DateRangeUpper_ValueChanged(sender As System.Object, e As System.EventArgs) Handles dtp_DateRangeUpper.ValueChanged
        dtp_DateRangeLower.MaxDate = dtp_DateRangeUpper.Value
    End Sub

    Private Sub cmd_DisplayStatistics_Click(sender As System.Object, e As System.EventArgs) Handles cmd_DisplayStatistics.Click
        Try
            Cursor = Cursors.WaitCursor
            Dim repoWysylka As New Repository(Of Wysylka)(_unitOfWork)
            Dim dateRangeSpec As New DateRangeSpecification(Of Wysylka)(dtp_DateRangeLower.Value.Date, dtp_DateRangeUpper.Value.Date)
            Dim wysylki As IEnumerable(Of Wysylka) = repoWysylka.GetAllMatching(dateRangeSpec)

            Dim drutyWyslane As IEnumerable(Of DrutWyslany) = wysylki.SelectMany(Function(x) x.PaczkiWysylki.SelectMany(Function(y) y.Druty))

            'Dim waga As Double = wysylki.SelectMany(Function(x) x.PaczkiWysylki).Sum(Function(x) x.Waga)


            FillDrutWyslanyTable(drutyWyslane)

            Dim pracownicy As IEnumerable(Of Pracownik) = New Repository(Of Pracownik)(_unitOfWork).GetAll()
            _dictDrutPracownikow = New Dictionary(Of Pracownik, IList(Of Drut))
            For Each pracownik As Pracownik In pracownicy
                _dictDrutPracownikow.Add(pracownik, New List(Of Drut))

            Next
            

            For Each drutWyslany As DrutWyslany In drutyWyslane
                Dim druty As New List(Of Drut)
                druty.Add(drutWyslany.Drut)

                While druty.Any
                    Dim drucik As Drut = druty.First()
                    _dictDrutPracownikow(drucik.Pracownik).Add(drucik)
                    druty.AddRange(drucik.Rodzice.Where(Function(x) Not x.WyznMaterialProdukcyjny).Select(Function(x) x.DrutRodzic).Where(Function(x) Not IsNothing(x)))
                    druty.RemoveAll(Function(x) x.Equals(drucik))
                End While
            Next

            FillPracownicyTable(_dictDrutPracownikow)
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Błąd", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub


    Private Sub FillDrutWyslanyTable(ByVal drutWyslanyList As IEnumerable(Of DrutWyslany))
        dgv_WyslanyDrut.Rows.Clear()
        Dim rowIndex As Integer
        Dim totalWeight As Decimal = 0

        For Each drutWyslany As DrutWyslany In drutWyslanyList
            Dim weight As Decimal = CType(If(drutWyslany.Drut.Kontrola.Any(), drutWyslany.Drut.Kontrola.First().Ilosc, 0), Decimal)
            totalWeight += weight

            rowIndex = dgv_WyslanyDrut.Rows.Add(
                rowIndex + 1,
                drutWyslany.Id,
                weight)
        Next

        txt_WyslanyDrutSuma.Text = totalWeight.ToString() + " kg"
    End Sub


    Private Function GetMaterialDensity() As Double
        Return 0.00849 'avg
        '   MIEDŹ(8, 96)
        '  MOSIĄDZ(8, 67)
        'CHROMONIKIEL(7, 85)

    End Function

    ' wtf?!
    Private Function EstimateWireLength(diameter As Double, weight As Double) As Double
        Return weight / GetMaterialDensity() / (Math.PI * Math.Pow(diameter / 20, 2)) / 100
    End Function




    Private Sub FillPracownicyTable(ByVal dictDrutPracownikow As IDictionary(Of Pracownik, IList(Of Drut)))
        dgv_Pracownicy.Rows.Clear()
        Dim rowIndex As Integer
        Dim totalLength As Double = 0


        For Each pair As KeyValuePair(Of Pracownik, IList(Of Drut)) In dictDrutPracownikow
            Dim weight As Decimal = CType(pair.Value.Sum(Function(x) x.Rodzice.Sum(Function(y) y.Waga)), Decimal)
            Dim length As Double = pair.Value.Sum(Function(x) EstimateWireLength((x.WymiarMax + x.WymiarMin) / 2, x.Rodzice.Sum(Function(y) y.Waga)))
            totalLength += length

            If weight > 0 Then
                rowIndex = dgv_Pracownicy.Rows.Add(
                rowIndex + 1,
                pair.Key.ToString(),
                Math.Round(length / 1000, 2),
                Math.Round(weight, 1))
                dgv_Pracownicy.Rows(rowIndex).Tag = pair.Key
            End If
        Next
        txt_DrutDlugosc.Text = Math.Round(totalLength / 1000, 0).ToString() + " km"
    End Sub

    Private Sub FillDrutPracownikaTable(ByVal druty As IEnumerable(Of Drut))
        dgv_DrutPracownika.Rows.Clear()
        Dim rowIndex As Integer
        Dim totalWeight As Decimal = 0

        For Each drut As Drut In druty
            Dim weight As Decimal = CType(If(drut.Kontrola.Any(), drut.Kontrola.First().Ilosc, drut.Rodzice.Sum(Function(x) x.Waga)), Decimal)
            totalWeight += weight

            rowIndex = dgv_DrutPracownika.Rows.Add(
                rowIndex + 1,
                drut.Id,
                weight)
            dgv_DrutPracownika.Rows(rowIndex).Tag = drut
        Next

        txt_PracownikSuma.Text = totalWeight.ToString() + " kg"
    End Sub



    Private Sub dgv_Pracownicy_SelectionChanged(sender As System.Object, e As EventArgs) Handles dgv_Pracownicy.SelectionChanged
        If dgv_Pracownicy.SelectedRows.Count > 0 Then
            Dim selectedPracownik As Pracownik = CType(dgv_Pracownicy.SelectedRows(0).Tag, Pracownik)
            If Not IsNothing(selectedPracownik) Then
                FillDrutPracownikaTable(_dictDrutPracownikow(selectedPracownik))
            Else
                dgv_DrutPracownika.Rows.Clear()
            End If
        Else
            dgv_DrutPracownika.Rows.Clear()
        End If
    End Sub

    Private Sub dgv_DrutPracownika_CellDoubleClick(sender As System.Object, e As EventArgs) Handles dgv_DrutPracownika.CellDoubleClick
        Try
            If dgv_DrutPracownika.SelectedRows.Count > 0 Then
                Cursor = Cursors.WaitCursor
                Dim drut As Drut = CType(dgv_DrutPracownika.SelectedRows(0).Tag, Drut)
                Dim frmTrDrut As New frmTrDrut(drut)
                frmTrDrut.MdiParent = Me.MdiParent
                frmTrDrut.Show()
            End If

        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub
End Class